# app.py
from flask import Flask, request, jsonify, render_template, session, redirect, url_for
from functools import wraps
import json
import os

app = Flask(__name__)
app.secret_key = os.urandom(24)

# --- 数据存储 ---
DATA_FILE = "data_storage.json"
# 账号权限表
USER_PERMISSIONS = {
    'admin': ['group_mapping', 'keyword_mapping', 'faq_mapping'],
    'user': ['keyword_mapping', 'faq_mapping'],
    'myf': ['group_mapping']
}

# --- 函数：加载数据 ---
def load_data():
    """从 JSON 文件加载数据"""
    if os.path.exists(DATA_FILE):
        try:
            with open(DATA_FILE, 'r', encoding='utf-8') as f:
                data = json.load(f)
                print(type(data))
                # for keys, values in data.items():
                #     print(keys)
                # 基本验证，确保是字典且包含预期的模块键
                if isinstance(data, dict) and all(k in data for k in ["group_mapping", "keyword_mapping", "faq_mapping"]):
                     print(f"成功从 {DATA_FILE} 加载数据。")
                     return data
                else:
                     print(f"警告: {DATA_FILE} 格式不正确，将使用默认数据。")
                     # 如果文件存在但格式不对，返回默认数据避免错误
                     return get_default_data()
        except (json.JSONDecodeError, IOError) as e:
            print(f"警告: 读取 {DATA_FILE} 时出错 ({e})，将使用默认数据。")
            return get_default_data() # 读取错误也返回默认值
    else:
        print(f"提示: {DATA_FILE} 不存在，将使用默认数据并创建文件。")
        return get_default_data() # 文件不存在返回默认值

# --- 函数：获取默认数据 ---
def get_default_data():
     """返回初始的默认数据结构"""
     return {
        "group_mapping": {
            "技术交流群": "张三",
            "学习分享组": "李四",
        },
        "keyword_mapping": {
            "欢迎": "欢迎新成员！",
            "规则": "请遵守群规...",
        },
        "faq_mapping": {
            "如何提问": "请描述清楚问题背景和您尝试过的步骤。",
            "资料在哪": "群文件或公告有分享。",
        }
    }

# --- 函数：保存数据 ---
def save_data(data):
    """将数据保存到 JSON 文件"""
    try:
        with open(DATA_FILE, 'w', encoding='utf-8') as f:
            # indent=4 让 JSON 文件格式更易读
            # ensure_ascii=False 保证中文等非 ASCII 字符正常写入
            json.dump(data, f, indent=4, ensure_ascii=False)
        # print(f"数据已成功保存到 {DATA_FILE}") # 可选的调试输出
    except IOError as e:
        print(f"错误: 无法写入数据到 {DATA_FILE} ({e})")


def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'logged_in' not in session:
            return render_template('login.html')
        return f(*args, **kwargs)
    return decorated_function


data_store = load_data()

def get_user_permissions(username):
    """根据用户名获取用户权限"""
    # 默认返回空列表，表示没有权限
    return USER_PERMISSIONS.get(username, [])



@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        users = load_data()["user_infor"]

        if username in users and users[username] == password:
            session['logged_in'] = True
            session['username'] = username
            session['permissions'] = get_user_permissions(username)
            return redirect(url_for("index"))
        else:
            return render_template('login.html', error="用户名或密码错误")
    return render_template('login.html')
# 首页路由：渲染前端页面
@app.route('/')
@login_required
def index():
    """渲染主页面"""
    username = session.get('username')
    permissions = session.get('permissions', [])
    return render_template('index.html', username=username, permissions=permissions)

# 注意：我们不再需要 /api/<module_name>/all 这个路由了，可以删除或注释掉
# # 获取指定模块的所有数据 (这个路由现在不需要了)
@app.route('/api/<module_name>/all', methods=['GET'])
def get_all_data(module_name):
    """获取指定模块的所有数据"""
    if module_name in data_store:
        return jsonify(data_store[module_name])
    else:
        return jsonify({"error": f"模块 '{module_name}' 不存在"}), 404

# 查询数据 (Read)
@app.route('/api/<module_name>/<key>', methods=['GET'])
@login_required
def get_data(module_name, key):
    """根据键获取指定模块的数据"""
    if module_name not in data_store:
        return jsonify({"error": f"模块 '{module_name}' 不存在"}), 404
    if key in data_store[module_name]:
        # 查询成功，只返回对应的键值对
        return jsonify({key: data_store[module_name][key]})
    else:
        return jsonify({"error": f"键 '{key}' 在模块 '{module_name}' 中不存在"}), 404

# 添加数据 (Create)
@app.route('/api/<module_name>', methods=['POST'])
@login_required
def add_data(module_name):
    """向指定模块添加新的键值对"""
    if module_name not in data_store:
        return jsonify({"error": f"模块 '{module_name}' 不存在"}), 404

    content = request.json
    if not content or 'key' not in content or 'value' not in content:
        return jsonify({"error": "请求数据不完整，需要 'key' 和 'value'"}), 400

    key = content['key'].strip() # 去除前后空格
    value = content['value'] # 值通常不需要 trim

    if not key:
         return jsonify({"error": "键不能为空"}), 400

    if key in data_store[module_name]:
        return jsonify({"error": f"键 '{key}' 在模块 '{module_name}' 中已存在"}), 409

    data_store[module_name][key] = value
    save_data(data_store) # *** 数据变更后立即保存 ***
    return jsonify({"success": f"成功添加 '{key}': '{value}' 到模块 '{module_name}'"}), 201

# 修改数据 (Update)
@app.route('/api/<module_name>/<key>', methods=['PUT'])
@login_required
def update_data(module_name, key):
    """修改指定模块中指定键的值"""
    original_key = key # 保存原始 key 用于查找
    if module_name not in data_store:
        return jsonify({"error": f"模块 '{module_name}' 不存在"}), 404

    if original_key not in data_store[module_name]:
        return jsonify({"error": f"键 '{original_key}' 在模块 '{module_name}' 中不存在，无法修改"}), 404

    content = request.json
    if not content or 'value' not in content:
        return jsonify({"error": "请求数据不完整，需要 'value'"}), 400

    new_value = content['value']

    # 如果请求中也包含了 key，并且 key 和 URL 中的 key 不同，则认为是想重命名 key
    # (这个功能比较复杂，简单起见，我们这里只允许修改 value)
    # 如果需要修改 key，通常建议的操作是：删除旧 key，添加新 key
    new_key = content.get('key', original_key).strip()
    if new_key != original_key:
         # 如果键改变了，需要检查新键是否已存在
         if new_key in data_store[module_name]:
              return jsonify({"error": f"无法将键修改为 '{new_key}'，因为它在模块 '{module_name}' 中已存在"}), 409
         if not new_key:
             return jsonify({"error": "键不能为空"}), 400
         # 执行重命名（先添加新键值，再删除旧键）
         data_store[module_name][new_key] = new_value
         del data_store[module_name][original_key]
         message = f"成功将模块 '{module_name}' 中键 '{original_key}' 修改为 '{new_key}'，并将值更新为 '{new_value}'"
    else:
        # 只更新值
        data_store[module_name][original_key] = new_value
        message = f"成功将模块 '{module_name}' 中 '{original_key}' 的值修改为 '{new_value}'"

    save_data(data_store) # *** 数据变更后立即保存 ***
    return jsonify({"success": message})


# 删除数据 (Delete)
@app.route('/api/<module_name>/<key>', methods=['DELETE'])
@login_required
def delete_data(module_name, key):
    """删除指定模块中的指定键值对"""
    if module_name not in data_store:
        return jsonify({"error": f"模块 '{module_name}' 不存在"}), 404

    if key not in data_store[module_name]:
        return jsonify({"error": f"键 '{key}' 在模块 '{module_name}' 中不存在，无法删除"}), 404

    del data_store[module_name][key]
    save_data(data_store) # *** 数据变更后立即保存 ***
    return jsonify({"success": f"成功从模块 '{module_name}' 中删除键 '{key}'"})

# --- 运行应用 ---
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5001)